package com.geek.javase.ch10.work.collectionswork;

/*
 *@author wangpeng
 *2025/10/20 19:47
 *@description TODO
 */

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 按照斗地主的规则，完成**洗牌发牌**的动作。
 * 具体规则：
 * 使用54张牌打乱顺序,三个玩家参与游戏，三人交替摸牌，每人17张牌，最后三张留作底牌。
 * 牌进行排序、拿大王的可以拿底牌。
 * <p>
 * 1.做牌  Card 花色color、数字num、索引index  --》 存储至List<Card>
 * 2.乱序  --> Collections的shuffle()
 * 3.发牌  --> 51张牌 %3  + 剩余3张牌作为底牌  --》 存储至List<Card>
 * 4.底牌  --> 拿取大王的可以拿底牌
 * 5.排序  --> 将各玩家的牌进行排序
 * <p>
 * "♠", "♥", "♣", "♦"
 * "2", "A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3"
 */

/**
 * 斗地主洗牌发牌程序
 */
public class CardDemo {

    // 花色数组
    private static final String[] COLORS = {"♠", "♥", "♣", "♦"};
    // 数字数组
    private static final String[] NUMBERS = {"2", "A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3"};

    public static void main(String[] args) {
        // 1. 做牌
        List<Card> allCards = createCards();
        System.out.println("初始牌堆共: " + allCards.size() + "张");

        // 2. 乱序（洗牌）
        Collections.shuffle(allCards);
        System.out.println("洗牌完成");

        // 3. 发牌
        List<Card> player1 = new ArrayList<>();
        List<Card> player2 = new ArrayList<>();
        List<Card> player3 = new ArrayList<>();
        List<Card> bottomCards = new ArrayList<>();

        dealCards(allCards, player1, player2, player3, bottomCards);

        // 4. 排序
        sortCards(player1);
        sortCards(player2);
        sortCards(player3);
        sortCards(bottomCards);

        // 5. 输出结果
        printResult(player1, player2, player3, bottomCards);

        // 6. 确定谁拿底牌
        determineBottomCardOwner(player1, player2, player3, bottomCards);
    }

    //创建扑克牌
    private static List<Card> createCards() {
        List<Card> cards = new ArrayList<>();
        int index = 0;

        // 添加大小王
        cards.add(new Card("", "大王", index++));
        cards.add(new Card("", "小王", index++));

        // 添加普通牌
        for (String number : NUMBERS) {
            for (String color : COLORS) {
                cards.add(new Card(color, number, index++));
            }
        }

        return cards;
    }

    //发牌
    private static void dealCards(List<Card> allCards, List<Card> player1,
                                  List<Card> player2, List<Card> player3,
                                  List<Card> bottomCards) {
        for (int i = 0; i < allCards.size(); i++) {
            Card card = allCards.get(i);

            if (i < 51) { // 前51张牌发给玩家
                switch (i % 3) {
                    case 0 : player1.add(card);
                    case 1 : player2.add(card);
                    case 2 : player3.add(card);
                }
            } else { // 最后3张作为底牌
                bottomCards.add(card);
            }
        }
    }

    //排序牌（按索引降序，即从大到小）
    private static void sortCards(List<Card> cards) {
        cards.sort((c1, c2) -> c2.getIndex() - c1.getIndex());
    }

    //输出结果
    private static void printResult(List<Card> player1, List<Card> player2,
                                    List<Card> player3, List<Card> bottomCards) {
        System.out.println("\n=== 发牌结果 ===");
        System.out.println("玩家1: " + formatCards(player1));
        System.out.println("玩家2: " + formatCards(player2));
        System.out.println("玩家3: " + formatCards(player3));
        System.out.println("底牌: " + formatCards(bottomCards));
    }

    //格式化牌的输出
    private static String formatCards(List<Card> cards) {
        StringBuilder sb = new StringBuilder();
        for (Card card : cards) {
            sb.append(card).append(" ");
        }
        return sb.toString().trim();
    }

    //确定谁拿底牌（拿到大王的玩家可以拿底牌）
    private static void determineBottomCardOwner(List<Card> player1, List<Card> player2,
                                                 List<Card> player3, List<Card> bottomCards) {
        System.out.println("\n=== 底牌分配 ===");

        // 检查哪个玩家有大王
        int bigJokerOwner = findBigJokerOwner(player1, player2, player3);

        if (bigJokerOwner != -1) {
            System.out.println("玩家" + bigJokerOwner + "拿到了大王，可以获得底牌！");

            // 将底牌加入对应玩家的手牌
            switch (bigJokerOwner) {
                case 1:{
                    player1.addAll(bottomCards);
                    sortCards(player1);
                    bottomCards.clear();
                    System.out.println("玩家1获得底牌后的手牌: " + formatCards(player1));
                }
                case 2 : {
                    player2.addAll(bottomCards);
                    sortCards(player2);
                    bottomCards.clear();
                    System.out.println("玩家2获得底牌后的手牌: " + formatCards(player2));
                }
                case 3 :{
                    player3.addAll(bottomCards);
                    sortCards(player3);
                    bottomCards.clear();
                    System.out.println("玩家3获得底牌后的手牌: " + formatCards(player3));
                }
            }
        } else {
            System.out.println("大王在底牌中，无人获得底牌");
        }
    }

    //查找大王的持有者
    private static int findBigJokerOwner(List<Card> player1, List<Card> player2, List<Card> player3) {
        if (hasBigJoker(player1)) return 1;
        if (hasBigJoker(player2)) return 2;
        if (hasBigJoker(player3)) return 3;
        return -1; // 大王在底牌中
    }

    //检查玩家是否有大王
    private static boolean hasBigJoker(List<Card> player) {
        return player.stream().anyMatch(card -> "大王".equals(card.getNumber()));
    }
}

class Card {

    private String color;  // 花色
    private String number; // 数字
    private int index;     // 索引（用于排序）

    public Card(String color, String number, int index) {
        this.color = color;
        this.number = number;
        this.index = index;
    }

    // Getter方法
    public String getColor() {
        return color;
    }

    public String getNumber() {
        return number;
    }

    public int getIndex() {
        return index;
    }

    @Override
    public String toString() {
        if (color.isEmpty()) {
            return number; // 大小王没有花色
        }
        return color + number;
    }
}


